<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2017/5/25 0025
 * Time: 15:23
 */

namespace classes;

use drunk\file;
use drunk\str;

class Node
{
    /**
     * 取当前访问的控制器方法节点code
     * @return string
     */
    public static function code_current()
    {
        $request = request();
        return str::name_underline($request->module())
            . '/' . str::name_underline($request->controller())
            . '/' . str::name_underline($request->action());
    }

    /**
     * 自动将控制器方法写入节点表
     */
    public static function generate()
    {
        $nodes = self::lists();
        $dao_node = db('node');
        foreach ($nodes as $code=>$node) {
            if ($dao_node->where('code', $code)->count()) continue; // 若加过了, 则不再继续
            $dao_node->insert($node);
        }
    }

    /**
     * 取(模块、控制器、方法)节点队列
     * (注意：若为多级控制器节点，则此方法暂时无法正确遍历出)
     */
    private static function lists()
    {
        $modules = file::lists_dir(APP_PATH, '*controller*', '*common*');
        $nodes = [];
        foreach ($modules as $k=>$module) {
            if (false === strpos($module, 'controller')) { // 模块
                $module_name = str::name_underline(pathinfo($module, PATHINFO_FILENAME));
                self::lists_node_push($nodes, '', $module_name);
            } else { // 控制器
                $controllers = file::lists_file($module, '', '*Base*'); // 匹配控制器
                foreach ($controllers as $controller) {
                    $controller_name = str::name_underline(pathinfo($controller, PATHINFO_FILENAME));
                    self::lists_node_push($nodes, $module_name, $controller_name, 1);
                    // 匹配控制器公共且非php内定方法
                    if (preg_match_all('/^(?:(?!private|protected).)+?function\s+((?!_)\w+)/m', file_get_contents($controller), $functions)) {
                        foreach ($functions[1] as $function) {
                            $function = str::name_underline($function);
                            self::lists_node_push($nodes, $module_name . '/' . $controller_name, $function, 2);
                        }
                    }
                }
            }
        }
        return $nodes;
    }

    /**
     * 节点组组装
     * @param array $nodes
     * @param string $pcode
     * @param string $name
     * @param int $level
     */
    private static function lists_node_push(&$nodes, $pcode, $name, $level = 0)
    {
        $code = $pcode ? $pcode . '/' . $name : $name;
        $nodes[$code] = [
            'code' => $code,
            'pcode' => $pcode,
            'name' => $name,
            'level' => $level,
        ];
    }
}